/**
 * 
 */
package swt.tray;

import java.io.IOException;
import java.util.Date;
import java.util.logging.Logger;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.ToolTip;
import org.eclipse.swt.widgets.Tray;
import org.eclipse.swt.widgets.TrayItem;

import swt.action.CountdownAction;
import swt.commons.Const;
import swt.commons.LogUtil;
import swt.commons.ResourceUtil;
import swt.commons.Utils;
import swt.screen.AutoShutdownSetup;
import swt.screen.SetupPasswordWindow;

import com.swtdesigner.SWTResourceManager;

/**
 * @author Thuc
 *
 */
public class SysTray {

	private static Logger log = LogUtil.getLogger();
	
	protected boolean result;
	
	protected Shell shell;
	protected Tray tray;
	private ToolTip tip;
	private TrayItem item;
	private MenuItem mItem;
	private MenuItem mItemResetPass;
	private MenuItem mItemExit;
	
	private String hour;
	private String minute;
	private String day;
	private CountdownAction countdown;
	private boolean firsttimeUseFlag = false;
	private String language;
	
	/**
	 * Constructor
	 * @param hour
	 * @param minute
	 */
	public SysTray(String day, String hour, String minute){
		this.day = day;
		this.hour = hour;
		this.minute = minute;
	}
	
	/**
	 * Open
	 * @return boolean
	 */
	public boolean open(){
		try {
			log.info("Open System Tray.");
			
			ResourceUtil resourceUtil = ResourceUtil.getInstance();
			// Check Language
			language = resourceUtil.getProperty(Const.KEY_LANGUAGE);
			// Setup language
			if (Utils.isNullEmpty(language)) {
				language = Const.LANGUAGE_EN;
				resourceUtil.setProperty(Const.KEY_LANGUAGE, language);
			}
			// Check first time using
			String isFirstTimeUse = resourceUtil.getProperty(Const.KEY_FIRST_USE);
			if (!Utils.isNullEmpty(isFirstTimeUse)) {
				this.firsttimeUseFlag = Boolean.getBoolean(isFirstTimeUse);
			}
			else {
				this.firsttimeUseFlag = true;
				resourceUtil.setProperty(Const.KEY_FIRST_USE, String.valueOf(false));
			}
			//
			createContents();
			startCountdown();
			while (!shell.isDisposed()) {
				if (!shell.getDisplay().readAndDispatch()){
					shell.getDisplay().sleep();
				}
			}
		} 
		catch (Exception e) {
			log.severe("Exception." + e.getMessage());
		}
		return result;
	}

	/**
	 * Create contents
	 * @param display
	 * @throws IOException 
	 */
	private void createContents() throws IOException {

		Display display = Display.getDefault();
		if (shell == null || shell.isDisposed()) {
			shell = new Shell(display);
		}
		
		final Rectangle disRect = display.getBounds();
		final int x = disRect.width-100;
		final int y = disRect.height-30;
		
		tip = new ToolTip(shell, SWT.BALLOON | SWT.ICON_INFORMATION);
		tip.setLocation(x, y);
		tip.setAutoHide(true);
		if (language.equals(Const.LANGUAGE_EN)) {
			if (this.firsttimeUseFlag) {
				tip.setMessage("Hidden to System Tray.");
				tip.setText("Auto Shutdown");
			}
		}
		else if (language.equals(Const.LANGUAGE_VN)) {
			if (this.firsttimeUseFlag) {
				tip.setMessage("Đã ẩn xuống system tray.");
				tip.setText("Auto Shutdown");
			}
		}
   
		tray = display.getSystemTray();
		if (tray == null) {
			log.info("The system tray is not available");
			return;
		}
		
		item = new TrayItem(tray, SWT.NONE);
		item.setImage(SWTResourceManager.getImage(Const.ICON_FILE));
		item.setToolTip(tip);
		if (language.equals(Const.LANGUAGE_EN)) {
			String tipText = "";
			if (!Utils.isNullEmpty(this.hour + this.minute)) {
				String today = Utils.formatDate(new Date(), Const.DATE_FORMAT);
				if (today.equals(this.day)) {
					tipText = this.hour + Const.COLON + this.minute;
				}
				else {
					tipText = this.day + "  " + this.hour + Const.COLON + this.minute;
				}
			}
			if (Utils.isNullEmpty(tipText)) {
				item.setToolTipText("Not yet setup shutdown timer.");
			}
			else {
				item.setToolTipText("Shutdown Timer: " + tipText);
			}
		}
		else if (language.equals(Const.LANGUAGE_VN)) {
			String tipText = "";
			if (!Utils.isNullEmpty(this.hour + this.minute)) {
				String today = Utils.formatDate(new Date(), Const.DATE_FORMAT);
				if (today.equals(this.day)) {
					tipText = this.hour + Const.COLON + this.minute;
				}
				else {
					tipText = this.day + "  " + this.hour + Const.COLON + this.minute;
				}
			}
			if (Utils.isNullEmpty(tipText)) {
				item.setToolTipText("Chưa thiết lập giờ tắt máy.");
			}
			else {
				item.setToolTipText("Giờ tắt máy: " + tipText);
			}
		}
		tip.setVisible(true);
		item.addListener(SWT.DefaultSelection, new Listener() {
			public void handleEvent(Event event) {
				openSetupTimerWindow();
			}
		});
		
		// Style must be pop up
		final Menu menu = new Menu(shell, SWT.POP_UP);
		// Creates a new menu item that terminates the program when selected
		mItem = new MenuItem(menu, SWT.NONE);
		mItem.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event event) {
				openSetupTimerWindow();
			}
		});
		
		mItemResetPass = new MenuItem(menu, SWT.NONE);
		mItemResetPass.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event event) {
				openSetupPasswordWindow();
			}
		});
		
		mItemExit = new MenuItem(menu, SWT.NONE);
		mItemExit.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event event) {
				exitAction();
			}
		});
		
		item.addListener(SWT.MenuDetect, new Listener() {
			public void handleEvent(Event event) {
				// We need to make the menu visible
				menu.setVisible(true);
			};
		});
		// Set display label of Controls
		setDisplayControlLabel();
	}
	
	/**
	 * Set display language
	 * @param language
	 * @throws IOException
	 */
	private void setDisplayControlLabel() throws IOException {
		if (language.equals(Const.LANGUAGE_EN)) {
			mItem.setText("Setup shutdown timer.");
			mItemResetPass.setText("Setup password.");
			mItemExit.setText("Quit.");
		}
		else if (language.equals(Const.LANGUAGE_VN)) {
			mItem.setText("Thiết lập giờ tắt máy.");
			mItemResetPass.setText("Thiết lập mật khẩu.");
			mItemExit.setText("Thoát.");
		}
	}
	
	/**
	 * openSetupTimerWindow
	 *
	 */
	private void openSetupTimerWindow() {

		log.info("Selected Open Setup Timer Screen.");
		tray.dispose();
		//
		stopCountdown();
		//
		SetupPasswordWindow window = new SetupPasswordWindow(this.shell, Const.CHECK_PASS);
		boolean retFlag = window.open();
		//
		if (!retFlag){
			open();
		}
		else {
			log.info("Exit System Tray.");
			shell.dispose();
			AutoShutdownSetup timerSetupWindow = new AutoShutdownSetup(this.day, this.hour, this.minute);
			timerSetupWindow.open();
		}
	}
	
	/**
	 * openSetupPasswordWindow
	 *
	 */
	private void openSetupPasswordWindow() {
		log.info("Selected Open Setup Password Screen menu.");
		tray.dispose();
		//
		stopCountdown();
		//
		boolean retFlag = checkPassword();
		// If Cancel, re-open System Tray
		if (!retFlag) {
			open();
		}
		else {
			retFlag = setupPassword();
			open();
		}
	}
	
	/**
	 * Exit
	 *
	 */
	private void exitAction() {
		log.info("Selected Exit app menu.");
		tray.dispose();
		//
		stopCountdown();
		//
		boolean retFlag = checkPassword();
		// If Cancel, re-open System Tray
		if (!retFlag) {
			open();
		}
		else {
			shell.dispose();
			log.info("Exit System Tray.");
			log.info("Exit app.");
		}
	}
	
	/**
	 * Open Setup Password Screen to check
	 * @return
	 */
	private boolean checkPassword() {
		SetupPasswordWindow window = new SetupPasswordWindow(this.shell, Const.CHECK_PASS);
		return window.open();
	}
	
	/**
	 * Open Setup Password Screen to setup
	 * @return
	 */
	private boolean setupPassword() {
		SetupPasswordWindow window = new SetupPasswordWindow(this.shell, Const.SETUP_PASS);
		return window.open();
	}
	
	/**
	 * start countdown
	 */
	private void startCountdown(){
		if (!Utils.isNullEmpty(this.hour + this.minute)) {
			log.info("Countdown start.");
			countdown = new CountdownAction(this.day, this.hour, this.minute);
			countdown.run();
		}
	}
	
	/**
	 * stop countdown
	 *
	 */
	private void stopCountdown(){
		if (null != countdown){
			log.info("Countdown stop.");
			countdown.dispose();
		}
	}
}
